JS Nativeのsleep関数ほしい
promise実装版より正確に制御できるsleep関数実装してくれMijinko_SD.icon (あんまり正確に制御できてしまうとユーザーのトラッキングに転用できてしまう問題があるかもだけど)
そもそもC言語のsleep関数でもシステムコール呼んだりとかでオーバーヘッドあるしプロセスの切り替え間隔があるから無理ではbsahd.icon
sleep前後でDate.now()して比較すればオーバーヘッドにかかった時間はわかる
code:js
function sleep(delay) {
return new Promise((resolve, _) => {
setTimeout(resolve, delay);
});
}
const iter = new Array(1000).fill(1);
const a = performance.now();
function pump() {
const a = iter.shift()
if(typeof a == "undefined"){
return;
}
return sleep(0).then(pump);
}
pump().then(()=>{
console.log(performance.now() - a)
})
以前個人的に測った際はsleep(0)でも20ms~50msぐらいの遅延が発生していた(Node.jsで計測した場合)
1000回sleepを呼び出して1662~2071msbsahd.icon
というかGCがある原理上完全に無理bsahd.icon
既に読み込み済みの単一プロセスの処理を一定時間止めるのにそこまで遅延が発生する想像がつかないけど・・・Mijinko_SD.icon
まあそういうものなんだろうな🤔
promiseは別プロセスに分離しているので遅延が発生するのは仕方がない
プロセスではないのではbsahd.icon
プロセス生成だとすると早すぎる
スレッドすら作らずにマイクロタスクで擬似スレッドしてたのでは
別スレッドかなんかだったかもしれないけれど忘れたMijinko_SD.icon
何かしら別のタスクを生成していた記憶はある
そのあたりはググって
promiseが嫌なら同期版もあるよbsahd.icon
code:js
function sleep(delay) {
const before = performance.now();
while (performance.now() < before + delay) {
// empty
}
}
const iter = new Array(1000).fill(1);
const a = performance.now();
for (const _ of iter) {
sleep(1);
}
console.log(performance.now() - a);
強引で草Mijinko_SD.icon
https://gyazo.com/c63fd5081008ccb482c53cd605d129e4
パフォーマンス的に問題がないなら、精度もいいし使えそう
あ、ちなみに他の処理(レンダリング含む)を全てブロックするし、CPU利用率も結構上がるbsahd.icon
参考として通常のsetTimeout版も入れておくbsahd.icon
code:js
const iter = new Array(1000).fill(1);
const a = performance.now();
function pump() {
return new Promise((resolve, reject) => {
const a = iter.shift();
if (typeof a == "undefined") {
resolve()
}
setTimeout(() => {
resolve(pump());
}, 0);
});
}
pump().then(() => {
console.log(performance.now() - a);
});
1000回setTimeoutを呼び出して1662~2071ms
身も蓋もないことをいうと、そんなに正確に待機する関数が必要な場面って、JS系であるのかな?takker.icon
これは実際そうなんだよな、JavaScript使うときで正確に秒数指定で待機したいケースに出会ったことがないから必要性を感じない綾坂こと.icon
科学計算系ならRust/Fortran/C++/Pythonを使おうという話になりそう
Pythonは科学計算には速度的には非力だった気がするbsahd.icon